/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙，邂逅框架梦]
 * 
 * https://zhiqim.org/project/zhiqim_framework/zhiqim_httpd.htm
 *
 * Zhiqim Httpd is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package org.zhiqim.httpd.context.returns;

import java.net.SocketException;

import org.zhiqim.httpd.HttpRequest;
import org.zhiqim.httpd.HttpResponse;
import org.zhiqim.httpd.context.core.Context;
import org.zhiqim.httpd.context.core.Return;
import org.zhiqim.httpd.util.Responses;

import org.zhiqim.zml.ZmlEngine;
import org.zhiqim.kernel.util.Htmls;
import org.zhiqim.httpd.util.Scripts;
import org.zhiqim.kernel.util.Validates;

/**
 * 响应警告信息，用于通过iframe提交信息时响应错误
 *
 * @version v1.0.0 @author zouzhigang 2017-8-21 新建与整理
 */
public class ReturnFrame implements Return
{
    @Override
    public void process(HttpRequest request) throws SocketException
    {
        Context context = (Context)request.getContext();
        ZmlEngine engine = context.getZmlEngine();
        if (engine.hasZml(_PATH_RETURN_FRAME_))
        {
            returnTemplate.process(request, _PATH_RETURN_FRAME_, null);
            return;
        }
        
        HttpResponse response = request.getResponse();
        String encoding = response.getCharacterEncoding();
        
        //1.Script头部
        StringBuilder strb = new StringBuilder();
        strb.append(_HTML_5_TYPE_).append(_BR_);
        strb.append(_HTML).append(_BR_);
        strb.append(_HEAD).append(_BR_);
        strb.append(Htmls.toTitle(request.getContextName()));
        strb.append(Htmls.toContentType(encoding));
        strb.append(_SCRIPT_BR);
        
        //2.组装告警函数
        buildAlertMsgFunction(request, strb);
        
        //3.组装回调函数
        buildCallbackFunction(request, strb);
        
        //4.Script尾部
        strb.append(SCRIPT_).append(_BR_);
        strb.append(HEAD_).append(_BR_);
        strb.append(HTML_).append(_BR_);

        //最后输出
        Responses.printAndCommit(response, strb, log);
    }
    
    /** 组装告警函数 */
    private void buildAlertMsgFunction(HttpRequest request, StringBuilder strb)
    {
        String message = request.getAlertMsg();
        if (Validates.isEmpty(message))
        {//无消息的直接回调
            strb.append("callback();").append(_BR_).append(_BR_);
            return;
        }
        
        //有消息的，弹出消息告警，后执行回调函数
        message = Scripts.formatAlertMsg(message);
        strb.append("if (parent.Z && parent.Z.onload && parent.Z.alert)").append(_BR_)
            .append("{").append(_BR_)
            .append(_FOUR_).append("parent.Z.alert(\"").append(message).append("\", callback, {type: \"").append(request.isResponseSuccess()?"success":"failure").append("\"});").append(_BR_)
            .append("}").append(_BR_)
            .append("else").append(_BR_)
            .append("{").append(_BR_)
            .append(_FOUR_).append("alert(\"").append(message).append("\");").append(_BR_)
            .append(_FOUR_).append("callback();").append(_BR_)
            .append("}").append(_BR_)
            .append(_BR_);
    }
    
    /** 组装回调函数 */
    private void buildCallbackFunction(HttpRequest request, StringBuilder strb)
    {
        int returnType = request.getForceReturnType();
        
        //1.函数头
        strb.append("function callback()").append(_BR_)
            .append("{").append(_BR_);
        
        //2.回调恢复按钮
        if (returnType != 0)
        {//跳转的，不作回调恢复按钮
            int formIndex = request.getParameterInt(_PARAM_FORM_INDEX_);
            if (formIndex != -1)
            {//恢复按钮
                strb.append(_FOUR_).append("if (parent.setFormButtonResume){").append(_BR_)
                    .append(_FOUR_).append(_FOUR_).append("parent.setFormButtonResume(").append(formIndex).append(");").append(_BR_)
                    .append(_FOUR_).append("}").append(_BR_).append(_BR_);
            }
        }
        
        //3.跳转
        switch (request.getForceReturnType())
        {
        case -1:
        case 1:
        case 2:
        case 3:
        {//-1.没有redirect,1.返回上一页,2.关闭本窗口,3.关闭对话框,这四项直接回空白页
            strb.append(_FOUR_).append("window.location.href = \"about:blank\";").append(_BR_);
            break;
        }
        case 4:
        {//调用javascript
            String redirect = request.getRedirect(_UTF_8_);
            strb.append(_FOUR_).append(redirect.substring("javascript:".length())).append(_BR_);
            break;
        }
        default:
        {//缺省表示正常连接
            //1.先清除可能的回车换行
            String redirect = request.getRedirect(_UTF_8_);
            redirect = redirect.replaceAll("\r", "");
            redirect = redirect.replaceAll("\n", "");
            
            //2.判断是否是有效的地址
            //  2.1 支持绝对地址//开头或http(s)://开头,如//www.zhiqim.com/index.htm,http://www.zhiqim.com/index.htm
            //  2.2 支持基于虚拟目录如当前虚拟目录是/或/admin,则绝对路径如/zhiqim.htm在处理时自动转为/zhiqim.htm和/admin/zhiqim.htm
            //  2.3 其他认为是相对路径，如zhiqim.htm,../zhiqim.htm之类的路径
            if (redirect.startsWith("/") && !redirect.startsWith("//"))
            {//如果是绝对路径,自动加上虚拟目录
                redirect = request.getContext().getRootPath(redirect);
            }

            strb.append(_FOUR_);
            
            int target = request.getResponseStatus();
            if (target == _601_REDIRECT_PARENT_)
                strb.append("parent.parent.location.href=\"");
            else if (target == _603_REDIRECT_TOP_)
                strb.append("top.location.href=\"");
            else
                strb.append("parent.location.href=\"");
            
            strb.append(redirect).append("\";").append(_BR_);
        }
        }
        
        //4.函数结尾
        strb.append("}").append(_BR_);
    }
}
